home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * Copyright (C) 1994 Silicon Graphics, Inc.
- *
- _______________________________________________________________________
- ______________ S I L I C O N G R A P H I C S I N C . ____________
- |
- | $Revision: 1.0 $
- |
- | Classes:
- | RevoSurfEngine
- |
- | Author(s) : Paul Isaacs
- |
- ______________ S I L I C O N G R A P H I C S I N C . ____________
- _______________________________________________________________________
- */
-
- #include "RevoSurfEngine.h"
-
- /////////////////////////////////////////////////////////////
- // RevoSurfEngine
- //
- /////////////////////////////////////////////////////////////
- SO_ENGINE_SOURCE(RevoSurfEngine);
-
-
- void
- RevoSurfEngine::initClass()
- {
- SO_ENGINE_INIT_CLASS(RevoSurfEngine, SoEngine, "Engine" );
- }
-
- RevoSurfEngine::RevoSurfEngine()
- {
- SO_ENGINE_CONSTRUCTOR(RevoSurfEngine);
-
- // Inputs:
- // Two points that define axis to revolve around.
- SO_ENGINE_ADD_INPUT(axisPt1, (SbVec3f(0, 1, 0)));
- SO_ENGINE_ADD_INPUT(axisPt2, (SbVec3f(0, 0, 0)));
-
- // Coordinates that will be rotated about the axis.
- SO_ENGINE_ADD_INPUT(profileCoords, (SbVec3f(0, 0, 0)));
-
- // Angle of rotation between successive columns of points.
- SO_ENGINE_ADD_INPUT(angle, (.3));
-
- // Outputs:
- // This output is a grid of coordinates that comprise the surface
- SO_ENGINE_ADD_OUTPUT(gridOfCoords, SoMFVec3f);
-
- // Use this output if connecting to an SoIndexedFaceSet
- // (This is better than SoQuadMesh if you want to see creases)
- SO_ENGINE_ADD_OUTPUT(faceIndices, SoMFLong);
-
- // Used to see if number of rows or columns changes.
- oldVertsPerCol = 0;
- oldVertsPerRow = 0;
- }
-
- RevoSurfEngine::~RevoSurfEngine()
- {
- }
-
- void
- RevoSurfEngine::evaluate()
- {
- #define MY_PI 3.14159
- #define MY_TWO_PI 2 * 3.14159
-
- // Get origin and direction of axis of rotation.
- SbLine rotAxis( axisPt1.getValue(), axisPt2.getValue() );
- SbVec3f axisDir = rotAxis.getDirection();
- SbVec3f axisPos = rotAxis.getPosition();
-
- // Calculate the angle of rotation in range between -PI and PI
- float rotAngle = angle.getValue();
- // Avoid bad value
- if (rotAngle == 0)
- rotAngle = .1;
- // Get angle between -PI and PI
- while (rotAngle > MY_PI)
- rotAngle -= MY_TWO_PI;
- while (rotAngle < -MY_PI)
- rotAngle += MY_TWO_PI;
-
- // Calculate numRows, numCols, numCoords
- // Add 1 for initial point,
- // then add one for each rotation we can acheive before hitting 2PI.
- // then add 1 for final point.
- long numCols = 1 + floor(MY_TWO_PI / fabs(rotAngle)) + 1;
- long numRows = profileCoords.getNum();
- long numCoords = numRows * numCols;
- if ((numRows <= 1) || (numCols <= 1))
- return;
-
- // Set size of scratch field. Use this to save memory between evaluations
- scratchVecField.setNum( (int) numCoords );
- SbVec3f *myVecs = scratchVecField.startEditing();
-
- // For each Column:
- SbRotation colRot;
- SbVec3f thePt;
- for (int col = 0; col < numCols; col++) {
-
- long curInd = col;
-
- // Calculate Rotation of points for this column.
- // Final column is not rotated, however.
- if (col != numCols - 1)
- colRot.setValue( axisDir, rotAngle * col );
- else
- colRot.setValue( axisDir, 0 );
-
- // For each Row:
- for (int row = 0; row < numRows; row++ ) {
-
- // Translate by -axisPos and undo this after the rotation.
- // This makes rotation occur around axis instead of
- // around origin.
- thePt = profileCoords[row] - axisPos;
-
- // Rotate profile coord by rotation.
- // Value is put into myVecs[curInd]
- colRot.multVec( thePt, thePt );
-
- // Undo translation offset and assign into myVecs[curInd]
- myVecs[curInd] = thePt + axisPos;
-
- curInd += numCols;
- }
- }
-
- // Set output values.
- if (gridOfCoords.getNumConnections())
- SO_ENGINE_OUTPUT(gridOfCoords, SoMFVec3f,
- setValues(0,(int)numCoords,myVecs));
-
- // The faceIndices output contains indices for drawing surface as
- // triangular faces.
- // It only changes if the number of rows or columns changes.
- if ( oldVertsPerRow != numCols || oldVertsPerCol != numRows ) {
- loadFaceIndices( numRows, numCols );
- oldVertsPerRow = numCols;
- oldVertsPerCol = numRows;
- }
-
- #undef MY_PI
- #undef MY_TWO_PI
- }
-
- void
- RevoSurfEngine::loadFaceIndices( long numRows, long numCols )
- {
- // Calculate and allocate proper number of longs
- long numTris = (numRows - 1) * (numCols - 1) * 2;
- int numLongs = (int) (4 * numTris);
- long *myLongs = new long[numLongs];
-
- // For each topological upper row
- long curUpLeft, curLowLeft, curLongInd = 0;
- for (int row = 0; row < numRows - 1; row++ ) {
- curUpLeft = row * numCols;
- curLowLeft = curUpLeft + numCols;
-
- // For each topological left column
- for (int col = 0; col < numCols - 1; col++ ) {
-
- // Indices for upper left triangle
- myLongs[curLongInd++] = curUpLeft;
- myLongs[curLongInd++] = curUpLeft + 1;
- myLongs[curLongInd++] = curLowLeft;
- myLongs[curLongInd++] = -1;
-
- // Indices for lower left triangle
- myLongs[curLongInd++] = curLowLeft + 1;
- myLongs[curLongInd++] = curLowLeft;
- myLongs[curLongInd++] = curUpLeft + 1;
- myLongs[curLongInd++] = -1;
-
- // Increment indices of corners.
- curUpLeft++;
- curLowLeft++;
- }
- }
-
- SO_ENGINE_OUTPUT(faceIndices, SoMFLong,
- setValues(0, numLongs, myLongs));
-
- // Delete array of longs
- delete [] myLongs;
- }
-